<?


define('SSLIB_Database', TRUE);

class ErrSql extends Err
{
	private $query = "";
	private $dbname = "";
		
	function __construct($message, $query, $dbname, $code = 0)
	{
		$this->query = $query;
		$this->dbname = $dbname;
		parent::__construct($message, $code);
	}
		
	function __toString()
	{
		return sslib_exception_format($this->getCode(), 
		$this->getMessage().
		"\n".__T('query').": [LONGTEXT]$this->query[/LONGTEXT] \n ".__T('database').": $this->dbname \n", 
		$this->getFile(), $this->getLine(), 
		__T('error'),  
		$this);
	}
	
}


class Sql
{
	static function Escape($var)
	{
		return pg_escape_string($var);
	}
	static function Quote($db_var, $is_var = true)
	{
		if($is_var)
		{
			if($db_var == '0')	return "'0'";
			if (empty($db_var))	{	return 'NULL';				} 
			else 				{	return "'$db_var'";		}
		}
		else 
		{
				return "\"$db_var\"";
		}
	}
	static function QuoteColumn($db_var, $is_var = true)
	{
		return '"'.mysql_escape_string($db_var).'"';
	}
	static function QuoteValue($db_var, $is_var = true)
	{
		if($is_var)
		{
			if($db_var == '0')	return "'0'";
			if (empty($db_var))	{	return 'NULL';				} 
			else 				{	return "'".pg_escape_string($db_var)."'";		}
		}
	}
	static function SetQuery($val, $trim = true)
	{
		$ret = array();
		foreach($val as $key => $v)
		{
			if($trim)	$v = trim($v);
			$ret[] = "\"$key\" = ".Sql::Quote($v);
		}
		$ret = join(",", $ret);
		return ' '.$ret;
	}
	static function ValuesQuery($val, $trim = true)
	{
		$values = "";
		
		$keys = "(";
		$i = 0;
		foreach($val as $key => $v)
		{
			if($trim)	$v = trim($v);
			$i++;
			/*if(empty($v))
			{
				$v .= "NULL";
			}*/
			$keys .= Sql::Quote($key, false);
			
			if($v == "localtime()")
			{ 
				$values .= $v;
			}
			else
			{
				$v = str_replace("'", '\\\'', $v);
				$values .= Sql::Quote($v);
			}
				
			if($i < count($val))
			{
				$values .= ", ";
				$keys .= ", ";
				
			}
		}
		$keys .= ") VALUES(" . $values . ")";
		return ' '.$keys;
	}
	static function Limit($from, $to)
	{
		return " OFFSET $from ".($to?"LIMIT $to ":'');
	}
}
class Data
{
	function Vis($template, $callback = null, $isfile = true){return $this->Visualize($template,$callback,$isfile);}
	function Visualize($template, $callback = null, $isfile = true)
	{
		ob_start();
		if(!defined("SSLIB_Template")) die(__FILE__." Template class missing");
		
		if(!$this->result) return FALSE;
		
		while($arr = pg_fetch_assoc($this->result))
		{
			if($callback){$arr = call_user_func($callback, $arr);}
			if(is_array($arr))
			{
				if($isfile)	{echo Template::CompileFile($arr, $template);	}
				else 		{echo Template::Compile($arr, $template);		}
			}
		}

		
		return ob_get_clean();		
	}
	
	
	private $result = null;
	public function __construct($result)
	{
		$this->result = $result;
	}
	function __destruct()
	{
		if(!empty($this->result))
		{
				pg_free_result($this->result);
		}
	}
	function Row()
	{
		$this->SelfTest();
		return pg_fetch_assoc($this->result);
	}
	function Count()
	{
		return pg_num_rows($this->result);
	}
	
	
	function All()
	{
		if($this->result == null) return FALSE;
		$arr =  pg_fetch_assoc($this->result);
		return (sizeof($arr) === 1)?$arr[0]:$arr;
	}
	function Length()
	{
		return pg_num_rows($this->result);
	}
	function IsEmpty()
	{
		if($this->result == null) return true;
		return ($this->Length() > 0)?false:true;
	}
	private function SelfTest(){}
	function Value()                                                                                                                                                       
	{                            
		if($this->result == null) return FALSE;                                                                                                                                      
		$arr = pg_fetch_row($this->result);
		return is_array($arr)?$arr[0]:FALSE;                                                                                                                                                 
	}
}




class Database
{
	private $pgdb = null;
	private $lastoid = null;
	public function LastInseredId(){return $this->LastInseredOid();}
	public function LastInseredOid()
	{
		return $this->lastoid;
	}
	public function Begin()
	{
		pg_query($this->pgdb, "BEGIN");
	}
	public function Commit()
	{
		pg_query($this->pgdb, "COMMIT;");
	}
	
	public function __construct()
	{
		//global $sslib_db_host, $sslib_db_port, $sslib_db_name, $sslib_db_user,$sslib_db_password;
		//Sslib::Variable('database.host'),Sslib::Variable('database.user'), Sslib::Variable('database.password')
		//TODO: непонятки с хостером.  нужно давать корректную строку (убирать пустое.)	
		$this->pgdb = pg_pconnect(
			'host='.Sslib::Variable('database.host').
			(Sslib::Variable('database.port')?' port='.Sslib::Variable('database.port'):'').
			' dbname='.Sslib::Variable('database.base').
			' user='.Sslib::Variable('database.user').
			' password='.Sslib::Variable('database.password'));
		$this->Query("SET TIME ZONE 'Europe/Moscow';");
	}
	function SendQuery($query)
	{
		pg_send_query($this->pgdb, $query);
	}
	function Query($query)
	{
		$result = pg_query($this->pgdb, $query);	
		
		if($result === FALSE)
			new ErrSql(pg_errormessage($this->pgdb), $query, pg_dbname($this->pgdb));
		if(pg_result_status($result) == PGSQL_COMMAND_OK)
			$this->lastoid = pg_getlastoid($result);
		else 
			$this->lastoid = null;
		return new Data($result);
	}
	function QueryToArray($query)
	{
		$data = $this->Query($query);
		return $data->All();
	}
	function SendInsert($table, $values)
	{
		$query = "INSERT INTO $table ".Sql::ValuesQuery($values).";";
		$this->SendQuery($query);
	}
	function Insert($table, $values)
	{
		$query = "INSERT INTO $table ".Sql::ValuesQuery($values).";";
		$this->Query($query);
	}
	function __destruct()
	{
		if($this->pgdb !== null)
		{
			$stat = pg_connection_status($this->pgdb);
  		if ($stat === PGSQL_CONNECTION_OK) {pg_close($this->pgdb);}
			$this->pgdb = null;
			$this->data = null;
		}
	}
	
	
}
?>